package coupon

import (
	sqlc "bp/db/sqlc"
	sharedConv "bp/internal/rpcserver/shared/conv"
	"bp/internal/service/entity/coupon"
	"bp/internal/service/param"
	couponGrpc "bp/rpc/gen/mwebapi/mcoupon"
)

func (s *CouponMWebApiImp) ConvMemberCouponPtrsToCouponIDs(ptrs []*sqlc.MemberCoupon) []int64 {
	r := make([]int64, 0, len(ptrs))
	tmp := make(map[int64]struct{})
	for _, ptr := range ptrs {
		couponID := ptr.CouponID
		if _, ok := tmp[couponID]; !ok {
			tmp[couponID] = struct{}{}
			r = append(r, couponID)
		}
	}
	return r
}

type CouponPtrEntityToPbFunc func(*sqlc.Coupon) *couponGrpc.CouponEntity

// ConvCouponPtrEntityToPb get func of *sqlc.Coupon => *couponGrpc.CouponEntity
func (s *CouponMWebApiImp) ConvCouponPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
) CouponPtrEntityToPbFunc {
	return func(ptr *sqlc.Coupon) *couponGrpc.CouponEntity {
		if ptr == nil {
			return nil
		}
		return &couponGrpc.CouponEntity{
			Id:                      ptr.ID,
			Name:                    ptr.Name,
			Desc:                    ptr.Desc.String,
			Tags:                    ptr.Tags,
			OfferCategory:           ptr.OfferCategory,
			OfferType:               ptr.OfferType,
			CouponStatus:            ptr.CouponStatus,
			Bg:                      ptr.Bg.String,
			NeedVerifyQualification: ptr.NeedVerifyQualification,
			QualifyTypes:            ptr.QualifyTypes,
			Price:                   ptr.Price,
			Quota:                   ptr.Quota,
			OffMaximum:              ptr.OffMaximum,
			UsePeriodType:           ptr.UsePeriodType,
			Days:                    ptr.Days.Int32,
			AvailableAfterGotDays:   ptr.AvailableAfterGotDays.Int32,
			UseBegined:              sqlc.GoNTimeToPBTimestamp(ptr.UseBegined),
			UseEnded:                sqlc.GoNTimeToPBTimestamp(ptr.UseEnded),
			UseTimeRanges:           sharedConv.ConvTimeRangeArrayEntityToPb(ptr.UseTimeRanges),
			DateChooseType:          ptr.DateChooseType.String,
			Weekdays:                ptr.Weekdays,
			Monthdays:               ptr.Monthdays,
			UseScenes:               ptr.UseScenes,
			Scope:                   ptr.Scope,
			ItemCategoryConfs:       sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
			ItemConfs:               sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
		}
	}
}

type MemberCouponPtrEntityToPbFunc func(*sqlc.MemberCoupon) *couponGrpc.MemberCouponEntity
type MemberCouponPtrArrayEntityToPbFunc func([]*sqlc.MemberCoupon) []*couponGrpc.MemberCouponEntity

// ConvCouponPtrEntityToPb get func of *sqlc.MemberCoupon => *couponGrpc.MemberCouponEntity
func (s *CouponMWebApiImp) ConvMemberCouponPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
	couponPtr *sqlc.Coupon,
) MemberCouponPtrEntityToPbFunc {
	return func(ptr *sqlc.MemberCoupon) *couponGrpc.MemberCouponEntity {
		if ptr == nil {
			return nil
		}
		v := &couponGrpc.MemberCouponEntity{
			Id:                 ptr.ID,
			Sn:                 ptr.Sn,
			Name:               ptr.Name,
			Desc:               ptr.Desc.String,
			Tags:               ptr.Tags,
			OfferCategory:      ptr.OfferCategory,
			OfferType:          ptr.OfferType,
			MemberCouponStatus: ptr.MemberCouponStatus,
			Bg:                 ptr.Bg.String,
			Price:              ptr.Price,
			Quota:              ptr.Quota,
			OffMaximum:         ptr.OffMaximum,
			Begined:            sqlc.GoTimeToPBTimestamp(ptr.Begined),
			Ended:              sqlc.GoTimeToPBTimestamp(ptr.Ended),
			UseTimeRanges:      sharedConv.ConvTimeRangeArrayEntityToPb(ptr.UseTimeRanges),
			DateChooseType:     ptr.DateChooseType.String,
			Weekdays:           ptr.Weekdays,
			Monthdays:          ptr.Monthdays,
			UseScenes:          ptr.UseScenes,
			ItemCategoryConfs:  sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
			ItemConfs:          sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
		}
		if couponPtr != nil {
			v.Scope = couponPtr.Scope
		}
		return v
	}
}

// ConvCouponPtrEntityToPb get func of *sqlc.MemberCoupon => *couponGrpc.MemberCouponEntity
func (s *CouponMWebApiImp) ConvMemberCouponPtrEntityToPbWithoutItemInfo(couponPtr *sqlc.Coupon) MemberCouponPtrEntityToPbFunc {
	return func(ptr *sqlc.MemberCoupon) *couponGrpc.MemberCouponEntity {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		return s.ConvMemberCouponPtrEntityToPb(itemCategoryPtrs, itemPtrs, couponPtr)(ptr)
	}
}

// ConvMemberCouponPtrArrayEntityToPb get func of []*sqlc.MemberCoupon => []*couponGrpc.MemberCouponEntity
func (s *CouponMWebApiImp) ConvMemberCouponPtrArrayEntityToPb(
	itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap,
	itemMap param.EntityIDToItemConfigurationPtrsMap,
	couponMap coupon.CouponIDToCouponPtrMap,
) MemberCouponPtrArrayEntityToPbFunc {
	return func(ptrs []*sqlc.MemberCoupon) (vPtrs []*couponGrpc.MemberCouponEntity) {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		var couponPtr *sqlc.Coupon
		for _, ptr := range ptrs {
			if itemCategoryMap != nil {
				itemCategoryPtrs = itemCategoryMap[ptr.CouponID]
			}
			if itemMap != nil {
				itemPtrs = itemMap[ptr.CouponID]
			}
			if couponMap != nil {
				couponPtr = couponMap[ptr.CouponID]
			}
			vPtrs = append(vPtrs, s.ConvMemberCouponPtrEntityToPb(itemCategoryPtrs, itemPtrs, couponPtr)(ptr))
		}
		return
	}
}

type CouponWithDistributionStatPtrEntityToPbFunc func(*sqlc.ListCouponWithDistributionStatsByIssuerAndDistributeSceneRow) *couponGrpc.CouponWithDistributionStatEntity
type CouponWithDistributionStatPtrArrayEntityToPbFunc func([]*sqlc.ListCouponWithDistributionStatsByIssuerAndDistributeSceneRow) []*couponGrpc.CouponWithDistributionStatEntity

// ConvCouponWithDistributionStatPtrEntityToPb get func of *sqlc.ListCouponWithStatsRow => *couponGrpc.CouponWithStatEntity
func (s *CouponMWebApiImp) ConvCouponWithDistributionStatPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
) CouponWithDistributionStatPtrEntityToPbFunc {
	return func(ptr *sqlc.ListCouponWithDistributionStatsByIssuerAndDistributeSceneRow) *couponGrpc.CouponWithDistributionStatEntity {
		if ptr == nil {
			return nil
		}
		v := &couponGrpc.CouponWithDistributionStatEntity{
			Self: &couponGrpc.CouponEntity{
				Id:                      ptr.ID,
				Name:                    ptr.Name,
				Desc:                    ptr.Desc.String,
				Tags:                    ptr.Tags,
				OfferCategory:           ptr.OfferCategory,
				OfferType:               ptr.OfferType,
				CouponStatus:            ptr.CouponStatus,
				Bg:                      ptr.Bg.String,
				NeedVerifyQualification: ptr.NeedVerifyQualification,
				QualifyTypes:            ptr.QualifyTypes,
				Price:                   ptr.Price,
				Quota:                   ptr.Quota,
				OffMaximum:              ptr.OffMaximum,
				UsePeriodType:           ptr.UsePeriodType,
				Days:                    ptr.Days.Int32,
				AvailableAfterGotDays:   ptr.AvailableAfterGotDays.Int32,
				UseBegined:              sqlc.GoNTimeToPBTimestamp(ptr.UseBegined),
				UseEnded:                sqlc.GoNTimeToPBTimestamp(ptr.UseEnded),
				UseTimeRanges:           sharedConv.ConvTimeRangeArrayEntityToPb(ptr.UseTimeRanges),
				DateChooseType:          ptr.DateChooseType.String,
				Weekdays:                ptr.Weekdays,
				Monthdays:               ptr.Monthdays,
				UseScenes:               ptr.UseScenes,
				Scope:                   ptr.Scope,
				ItemCategoryConfs:       sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
				ItemConfs:               sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
			},
			Stat: &couponGrpc.CouponDistributionStatEntity{
				DistributedCnt: ptr.DistributedCnt,
				GotCnt:         ptr.GotCnt,
			},
			YouGotCnt: ptr.YouGotCnt,
		}
		return v
	}
}

// ConvCouponWithDistributionStatPtrArrayEntityToPb get func of []*sqlc.ListCouponWithStatsRow => []*couponGrpc.CouponWithStatEntity
func (s *CouponMWebApiImp) ConvCouponWithDistributionStatPtrArrayEntityToPb(
	itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap,
	itemMap param.EntityIDToItemConfigurationPtrsMap,
) CouponWithDistributionStatPtrArrayEntityToPbFunc {
	return func(ptrs []*sqlc.ListCouponWithDistributionStatsByIssuerAndDistributeSceneRow) (vPtrs []*couponGrpc.CouponWithDistributionStatEntity) {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		for _, ptr := range ptrs {
			vPtrs = append(vPtrs, s.ConvCouponWithDistributionStatPtrEntityToPb(itemCategoryPtrs, itemPtrs)(ptr))
		}
		return
	}
}
